package org.tokaf.algorithm;

import java.util.ArrayList;
import java.util.Iterator;

import org.tokaf.TopKElement;
import org.tokaf.bestcolumnfinder.BestColumnFinder;
import org.tokaf.datasearcher.DataSearcher;
import org.tokaf.rater.Rater;

/**
 * <p>The implementation of naive algorithm. Computes the rank of all objects, accessing all rows
 * in every datasearcher.</p>
 * <p>Copyright (c) 2006</p>
 * @author Alan Eckhardt
 * @version 1.0
 */

public class NaiveAlgorithm extends Algorithm {

	/**
	 * This algorithm doesn't have threshold value.
	 */
	public TopKElement getThreshold() {
		return null;
	}

	public ArrayList naive() {
		boolean konec = false;
		while (konec != true) {
			//	int i = finder.findColumn(this);
			long startTime2 = System.nanoTime();
			for (int i = 0; i < data.length; i++) {
				if (finished[i] == true) {
					konec = checkEnd();
					continue;
				} else if (!data[i].hasNext()) {
					finished[i] = true;
					konec = checkEnd();
					continue;
				}

				long startTime = System.nanoTime();
				Object subject = data[i].getField(0);
				Object object = data[i].getField(2);
				dataTime = dataTime + System.nanoTime() - startTime;

				startTime = System.nanoTime();
				TopKElement newSubject = new TopKElement(subject.toString(),
						-1, data.length);
				TopKElement temp = findEntity(newSubject);
				searchTime = searchTime + System.nanoTime() - startTime;

				if (temp == null) {
					topKlist.put(newSubject.name, newSubject);
				} else
					newSubject = temp;
				startTime = System.nanoTime();
				newSubject.setRating(i, object, data[i]);
				newSubject.setPosition(i, data[i].getPosistion());
				newSubject.setFound(i, step);
				ratingTime = ratingTime + System.nanoTime() - startTime;
				step++;
				if (maxStep != -1 && maxStep >= step)
					break;
				startTime = System.nanoTime();
				if (data[i].advance() == -1) {
					finished[i] = true;
					konec = checkEnd();
				}
				dataTime = dataTime + System.nanoTime() - startTime;
			}
			rateTime = rateTime + System.nanoTime() - startTime2;
		}

		long startTime = System.nanoTime();
		Iterator<TopKElement> i = topKlist.values().iterator();
		while (i.hasNext()) {
			TopKElement newSubject = i.next();
			rater.rate(newSubject, data);
		}
		ratingTime = ratingTime + System.nanoTime() - startTime;
		rateTime = rateTime + System.nanoTime() - startTime;

		return createArrayList();
	}

	public ArrayList run() {

		long startTime = System.nanoTime();
		ArrayList a = null;
		if (data.length > 0) {
			a = naive();
		} else
			a = new ArrayList();
		runTime = System.nanoTime() - startTime;
		return a;
	}

	/**
	 * Constructor of Naive Algorithm
	 * 
	 * @param data
	 *            DataSearcher[]
	 * @param rater
	 *            Rater
	 * @param finder BestColumnFinder
	 *            
	 * @param prefix String
	 *            
	 * @param K int
	 *
	 */
	public NaiveAlgorithm(DataSearcher[] data, Rater rater,
			BestColumnFinder finder, String prefix, int K) {
		super(data, rater, finder, prefix, K);
	}

	/**
	 * Performs one step of algorithm.
	 * 
	 * @return the number of already performed steps
	 */
	public int step() {
		if (end)
			return -1;
		actColumn = finder.findColumn(this);
		if (actColumn == -1) {
			end = true;
			return -1;
		}

		Object subject = data[actColumn].getField(0);
		Object object = data[actColumn].getField(2);
		TopKElement newObject = new TopKElement(subject.toString(), -1,
				data.length);
		if (findEntity(newObject) == null) {
			topKlist.put(newObject.name, newObject);
		}
		newObject.setRating(actColumn, object, data[actColumn]);
		rater.rate(newObject, data);
		if (data[actColumn].advance() == -1) {
			finished[actColumn] = true;
			end = checkEnd();
		}

		actColumn++;
		return actColumn - 1;
	}

}
